#include <util/std.h>
#include "aiisp_hnr.h"
#include <ss_mpi_hnr.h>
#include <ss_mpi_isp.h>
#include <ss_mpi_ae.h>

ot_hnr_cfg aiisp_hnr::g_hnr_cfg;
td_s32 aiisp_hnr::g_hnr_cfg_id[OT_HNR_MAX_CFG_NUM] = {-1};
td_s32 aiisp_hnr::g_is_wdr_mode = 0;

aiisp_hnr::aiisp_hnr(int pipe)
    :m_pipe(pipe)
{
}

aiisp_hnr::~aiisp_hnr()
{
}

bool aiisp_hnr::init(const char* model_file,int w,int h,int is_wdr_mode)
{
    td_s32 ret = 0;

    ret = ss_mpi_hnr_init();
    if(ret != TD_SUCCESS)
    {
        printf("[%s]: ss_mpi_hnr_init failed with error 0x%x\n",__FUNCTION__,ret);
        return false;
    }

    memset(&g_hnr_cfg,0,sizeof(g_hnr_cfg));

    if(!aiisp::read_model(model_file,(ot_hnr_mem_info *)&(g_hnr_cfg.mem_info)))
    {
        printf("[%s]: read_model failed\n",__FUNCTION__);
        return false;
    }

    g_hnr_cfg.image_size.width = w;
    g_hnr_cfg.image_size.height = h;
    g_hnr_cfg.is_wdr_mode = TD_FALSE; 

    ret = ss_mpi_hnr_load_cfg(&g_hnr_cfg,&g_hnr_cfg_id[0]);
    if(ret != TD_SUCCESS)
    {
        printf("[%s]: ss_mpi_hnr_load cfg failed with error 0x%x\n",__FUNCTION__,ret);
        return false;
    }

    g_hnr_cfg.is_wdr_mode = TD_TRUE; 
    ret = ss_mpi_hnr_load_cfg(&g_hnr_cfg,&g_hnr_cfg_id[1]);
    if(ret != TD_SUCCESS)
    {
        printf("[%s]: ss_mpi_hnr_load cfg failed with error 0x%x\n",__FUNCTION__,ret);
        return false;
    }

    g_is_wdr_mode = TD_TRUE;

    return true;
}

void aiisp_hnr::release()
{
    if(g_hnr_cfg_id[0] != -1)
    {
        ss_mpi_hnr_unload_cfg(g_hnr_cfg_id[0]);
    }

    if(g_hnr_cfg_id[1] != -1)
    {
        ss_mpi_hnr_unload_cfg(g_hnr_cfg_id[1]);
    }

    ss_mpi_hnr_exit();

    if(g_hnr_cfg.mem_info.phys_addr != 0)
    {
        ss_mpi_sys_mmz_free(g_hnr_cfg.mem_info.phys_addr, g_hnr_cfg.mem_info.virt_addr);
    }
}

bool aiisp_hnr::start()
{
    td_s32 ret;

    ot_isp_black_level_attr black_level_attr;
    ret = ss_mpi_isp_get_black_level_attr(m_pipe, &black_level_attr);
    if(ret != TD_SUCCESS)
    {
        printf("[%s]: ss_mpi_isp_get_black_level_attr failed with error 0x%x\n",__FUNCTION__,ret);
        return false;
    }

    black_level_attr.user_black_level_en = TD_TRUE;
    for (int i = 0; i < OT_ISP_WDR_MAX_FRAME_NUM; i++)
    {
        for (int j = 0; j < OT_ISP_BAYER_CHN_NUM; j++)
        {
            black_level_attr.user_black_level[i][j] = 1200; /* user_black_level of hnr default as 1200 */
        }
    }
    ret = ss_mpi_isp_set_black_level_attr(m_pipe, &black_level_attr);
    if(ret != TD_SUCCESS)
    {
        printf("[%s]: ss_mpi_isp_set_black_level_attr failed with error 0x%x\n",__FUNCTION__,ret);
        return false;
    }

    ot_hnr_alg_cfg attr;
    attr.ref_mode = OT_HNR_REF_MODE_NORM;
    ret = ss_mpi_hnr_set_alg_cfg(m_pipe, &attr);
    if(ret != TD_SUCCESS)
    {
        printf("[%s]: ss_mpi_hnr_set_alg_cfg failed with error 0x%x\n",__FUNCTION__,ret);
        return false;
    }

    ret = ss_mpi_hnr_enable(m_pipe);
    if(ret != TD_SUCCESS)
    {
        printf("[%s]: ss_mpi_hnr_start failed with error 0x%x\n",__FUNCTION__,ret);
        return false;
    }

    ot_hnr_attr hnr_attr;
    ret = ss_mpi_hnr_get_attr(m_pipe, &hnr_attr);
    if(ret != TD_SUCCESS)
    {
        printf("[%s]: ss_mpi_hnr_get_attr failed with error 0x%x\n",__FUNCTION__,ret);
        return false;
    }

    hnr_attr.enable = TD_TRUE;
    hnr_attr.bnr_bypass = TD_FALSE;
    hnr_attr.normal_blend = TD_FALSE;
    hnr_attr.op_type = OT_OP_MODE_MANUAL;
    hnr_attr.manual_attr.param.sfs = 31; /* sfs: 31 */
    hnr_attr.manual_attr.param.tfs = 31; /* tfs: 31 */
    ret = ss_mpi_hnr_set_attr(m_pipe, &hnr_attr);
    if(ret != TD_SUCCESS)
    {
        printf("[%s]: ss_mpi_hnr_set_attr failed with error 0x%x\n",__FUNCTION__,ret);
        return false;
    }

    if(g_is_wdr_mode)
    {
        ot_isp_exposure_attr exp_attr;
        ot_isp_wdr_fs_attr fswdr_attr;

        ret = ss_mpi_isp_get_exposure_attr(m_pipe, &exp_attr);
        if(ret != TD_SUCCESS) 
        {
            printf("[%s]: ss_mpi_isp_get_exposure_attr failed with error 0x%x\n",__FUNCTION__,ret);
            return false;
        }    

        exp_attr.auto_attr.fswdr_mode = OT_ISP_FSWDR_LONG_FRAME_MODE;
        ret = ss_mpi_isp_set_exposure_attr(m_pipe, &exp_attr);
        if(ret != TD_SUCCESS)
        {
            printf("[%s]: ss_mpi_isp_set_exposure_attr failed with error 0x%x\n",__FUNCTION__,ret);
            return false;
        }    

        ret = ss_mpi_isp_get_fswdr_attr(m_pipe, &fswdr_attr);
        if(ret != TD_SUCCESS) 
        {
            printf("[%s]: ss_mpi_isp_get_fswdr_attr failed with error 0x%x\n",__FUNCTION__,ret);
            return false;
        }    

        fswdr_attr.wdr_merge_mode = OT_ISP_MERGE_WDR_MODE;
        ret = ss_mpi_isp_set_fswdr_attr(m_pipe, &fswdr_attr);
        if (ret != TD_SUCCESS)
        {
            printf("[%s]: ss_mpi_isp_set_fswdr_attr failed with error 0x%x\n",__FUNCTION__,ret);
            return false;
        }
    }

    return true;
}

void aiisp_hnr::stop()
{
    td_s32 ret;

    ret = ss_mpi_hnr_disable(m_pipe);
    if(ret != TD_SUCCESS)
    {
        printf("[%s]: ss_mpi_hnr_stop failed with error 0x%x\n",__FUNCTION__,ret);
        return ;
    }

    return ;
}


